package com.reservation.controller;

import com.reservation.common.ApiResponse;
import com.reservation.dto.CreateReservationRequest;
import com.reservation.dto.ReservationDTO;
import com.reservation.enums.ReservationStatus;
import com.reservation.service.ReservationService;
import javax.validation.Valid;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.*;

import java.util.List;

/**
 * 预定控制器
 */
@Slf4j
@RestController
@RequestMapping("/reservations")
@RequiredArgsConstructor
public class ReservationController {

    private final ReservationService reservationService;

    /**
     * 创建预定
     */
    @PostMapping
    public ApiResponse<ReservationDTO> createReservation(@Valid @RequestBody CreateReservationRequest request) {
        log.info("创建预定: {}", request);
        try {
            ReservationDTO reservation = reservationService.createReservation(request);
            return ApiResponse.success("预定创建成功", reservation);
        } catch (Exception e) {
            log.error("创建预定失败", e);
            return ApiResponse.error("创建预定失败: " + e.getMessage());
        }
    }

    /**
     * 确认预定
     */
    @PutMapping("/{id}/confirm")
    public ApiResponse<ReservationDTO> confirmReservation(@PathVariable Long id) {
        log.info("确认预定: reservationId={}", id);
        try {
            ReservationDTO reservation = reservationService.confirmReservation(id);
            return ApiResponse.success("预定确认成功", reservation);
        } catch (Exception e) {
            log.error("确认预定失败: reservationId={}", id, e);
            return ApiResponse.error("确认预定失败: " + e.getMessage());
        }
    }

    /**
     * 取消预定
     */
    @PutMapping("/{id}/cancel")
    public ApiResponse<ReservationDTO> cancelReservation(@PathVariable Long id) {
        log.info("取消预定: reservationId={}", id);
        try {
            ReservationDTO reservation = reservationService.cancelReservation(id);
            return ApiResponse.success("预定取消成功", reservation);
        } catch (Exception e) {
            log.error("取消预定失败: reservationId={}", id, e);
            return ApiResponse.error("取消预定失败: " + e.getMessage());
        }
    }

    /**
     * 完成预定
     */
    @PutMapping("/{id}/complete")
    public ApiResponse<ReservationDTO> completeReservation(@PathVariable Long id) {
        log.info("完成预定: reservationId={}", id);
        try {
            ReservationDTO reservation = reservationService.completeReservation(id);
            return ApiResponse.success("预定完成成功", reservation);
        } catch (Exception e) {
            log.error("完成预定失败: reservationId={}", id, e);
            return ApiResponse.error("完成预定失败: " + e.getMessage());
        }
    }

    /**
     * 获取用户的预定记录
     */
    @GetMapping("/user/{userId}")
    public ApiResponse<List<ReservationDTO>> getUserReservations(@PathVariable Long userId) {
        log.info("获取用户预定记录: userId={}", userId);
        try {
            List<ReservationDTO> reservations = reservationService.getUserReservations(userId);
            return ApiResponse.success("获取用户预定记录成功", reservations);
        } catch (Exception e) {
            log.error("获取用户预定记录失败: userId={}", userId, e);
            return ApiResponse.error("获取用户预定记录失败: " + e.getMessage());
        }
    }

    /**
     * 根据状态获取用户的预定记录
     */
    @GetMapping("/user/{userId}/status/{status}")
    public ApiResponse<List<ReservationDTO>> getUserReservationsByStatus(
            @PathVariable Long userId, 
            @PathVariable String status) {
        log.info("根据状态获取用户预定记录: userId={}, status={}", userId, status);
        try {
            ReservationStatus reservationStatus = ReservationStatus.fromCode(status);
            List<ReservationDTO> reservations = reservationService.getUserReservationsByStatus(userId, reservationStatus);
            return ApiResponse.success("获取用户预定记录成功", reservations);
        } catch (Exception e) {
            log.error("根据状态获取用户预定记录失败: userId={}, status={}", userId, status, e);
            return ApiResponse.error("获取用户预定记录失败: " + e.getMessage());
        }
    }

    /**
     * 根据ID获取预定记录
     */
    @GetMapping("/{id}")
    public ApiResponse<ReservationDTO> getReservationById(@PathVariable Long id) {
        log.info("根据ID获取预定记录: reservationId={}", id);
        try {
            return reservationService.getReservationById(id)
                    .map(reservation -> ApiResponse.success("获取预定记录成功", reservation))
                    .orElse(ApiResponse.notFound("预定记录不存在"));
        } catch (Exception e) {
            log.error("获取预定记录失败: reservationId={}", id, e);
            return ApiResponse.error("获取预定记录失败: " + e.getMessage());
        }
    }

    /**
     * 获取所有预定记录（管理员用）
     */
    @GetMapping
    public ApiResponse<List<ReservationDTO>> getAllReservations() {
        log.info("获取所有预定记录");
        try {
            List<ReservationDTO> reservations = reservationService.getAllReservations();
            return ApiResponse.success("获取所有预定记录成功", reservations);
        } catch (Exception e) {
            log.error("获取所有预定记录失败", e);
            return ApiResponse.error("获取所有预定记录失败: " + e.getMessage());
        }
    }

    /**
     * 统计用户预定数量
     */
    @GetMapping("/user/{userId}/count")
    public ApiResponse<Long> countUserReservations(@PathVariable Long userId) {
        log.info("统计用户预定数量: userId={}", userId);
        try {
            Long count = reservationService.countUserReservations(userId);
            return ApiResponse.success("统计用户预定数量成功", count);
        } catch (Exception e) {
            log.error("统计用户预定数量失败: userId={}", userId, e);
            return ApiResponse.error("统计用户预定数量失败: " + e.getMessage());
        }
    }

    /**
     * 统计指定状态的预定数量
     */
    @GetMapping("/count/status/{status}")
    public ApiResponse<Long> countReservationsByStatus(@PathVariable String status) {
        log.info("统计指定状态的预定数量: status={}", status);
        try {
            ReservationStatus reservationStatus = ReservationStatus.fromCode(status);
            Long count = reservationService.countReservationsByStatus(reservationStatus);
            return ApiResponse.success("统计预定数量成功", count);
        } catch (Exception e) {
            log.error("统计预定数量失败: status={}", status, e);
            return ApiResponse.error("统计预定数量失败: " + e.getMessage());
        }
    }
}
